{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在mnist数据集上测试self-train半监督算法\n",
    "\n",
    "本实验测试了两种self-train算法，\n",
    "- 第1种是将无标签数据集作为一个整体，选择样本时从整个无标签数据集中选择（有放回抽样）；\n",
    "- 第2种是将无标签数据集分成$N$份，选择样本时，每次在其中一份进行选择；\n",
    "\n",
    "第2种算法的速度要比第1种算法快，因为第2种算法每个迭代只需要在一个无标签数据子集上做预测（更快）；\n",
    "\n",
    "但是有一点难理解的时，第2种算法的预测正确率同样要比第1种算法高（不清楚为什么？）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.keras.datasets import mnist\n",
    "from tensorflow.keras.models import Sequential\n",
    "import tensorflow.keras.layers as L\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "# tf.enable_eager_execution()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "处理数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load dataset\n",
    "(xtr,ytr),(xte,yte) = mnist.load_data()\n",
    "xtr = np.expand_dims(xtr,3).astype('float32')/255.\n",
    "ytr = np.eye(10)[ytr]\n",
    "xte = np.expand_dims(xte,3).astype('float32')/255.\n",
    "yte = np.eye(10)[yte]\n",
    "perm = np.load('perm-60000.npy')\n",
    "\n",
    "# 100 label samples, 59900 unlabel samples\n",
    "xla = xtr[perm[0:100]]\n",
    "yla = ytr[perm[0:100]]\n",
    "xun = xtr[perm[100:]]\n",
    "yun = ytr[perm[100:]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构建模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Build Model\n",
    "model = Sequential([\n",
    "    L.Conv2D(64, (3,3), padding='same', activation='relu', name='conv1', input_shape=(28,28,1)),\n",
    "    L.MaxPooling2D((2,2), name='pool1'),\n",
    "    L.Dropout(0.2),\n",
    "    L.Conv2D(16, (3,3), padding='same', activation='relu', name='conv2'),\n",
    "    L.MaxPooling2D((2,2)),\n",
    "    L.Dropout(0.2),\n",
    "    L.Flatten(),\n",
    "    L.Dense(128),\n",
    "    L.Dropout(0.5),\n",
    "    L.Dense(10, activation='softmax')])\n",
    "model.compile(loss='categorical_crossentropy', \\\n",
    "              optimizer=tf.train.AdamOptimizer(0.001), \\\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用带标签数据训练数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000/10000 [==============================] - 1s 62us/step\n",
      "模型正确率：0.7968\n"
     ]
    }
   ],
   "source": [
    "# # Train the model with labeled sample\n",
    "# history = model.fit(x=xla, y=yla, batch_size=20, epochs=30, validation_data=(xte, yte), \\\n",
    "#           shuffle=True)\n",
    "# model.save_weights('./model/model.ckpt')\n",
    "model.load_weights('./model/model.ckpt')\n",
    "acc = model.evaluate(xte, yte)\n",
    "print('模型正确率：{}'.format(acc[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 61 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "61/61 [==============================] - 0s 6ms/step - loss: 3.0359e-05 - acc: 1.0000 - val_loss: 0.7328 - val_acc: 0.7966\n",
      "Train on 28853 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "28853/28853 [==============================] - 2s 83us/step - loss: 0.0180 - acc: 0.9951 - val_loss: 0.8683 - val_acc: 0.8186\n",
      "Train on 43911 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "43911/43911 [==============================] - 3s 78us/step - loss: 0.0405 - acc: 0.9862 - val_loss: 0.9724 - val_acc: 0.8294\n",
      "Train on 49126 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "49126/49126 [==============================] - 4s 77us/step - loss: 0.0565 - acc: 0.9798 - val_loss: 0.9426 - val_acc: 0.8441\n",
      "Train on 51860 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "51860/51860 [==============================] - 4s 75us/step - loss: 0.0563 - acc: 0.9805 - val_loss: 0.8724 - val_acc: 0.8556\n",
      "Train on 52991 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "52991/52991 [==============================] - 4s 75us/step - loss: 0.0502 - acc: 0.9818 - val_loss: 0.8486 - val_acc: 0.8654\n",
      "Train on 54393 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "54393/54393 [==============================] - 4s 75us/step - loss: 0.0551 - acc: 0.9793 - val_loss: 0.7665 - val_acc: 0.8732\n",
      "Train on 54976 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "54976/54976 [==============================] - 4s 75us/step - loss: 0.0513 - acc: 0.9809 - val_loss: 0.8253 - val_acc: 0.8740\n",
      "Train on 56055 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "56055/56055 [==============================] - 4s 75us/step - loss: 0.0559 - acc: 0.9797 - val_loss: 0.7093 - val_acc: 0.8810\n",
      "Train on 56178 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "56178/56178 [==============================] - 4s 75us/step - loss: 0.0505 - acc: 0.9812 - val_loss: 0.6713 - val_acc: 0.8897\n",
      "Train on 56831 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "56831/56831 [==============================] - 4s 76us/step - loss: 0.0551 - acc: 0.9799 - val_loss: 0.6448 - val_acc: 0.8927\n",
      "Train on 56996 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "56996/56996 [==============================] - 4s 77us/step - loss: 0.0498 - acc: 0.9813 - val_loss: 0.6607 - val_acc: 0.8950\n",
      "Train on 57583 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "57583/57583 [==============================] - 4s 75us/step - loss: 0.0550 - acc: 0.9792 - val_loss: 0.6358 - val_acc: 0.8957\n",
      "Train on 57742 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "57742/57742 [==============================] - 4s 76us/step - loss: 0.0533 - acc: 0.9803 - val_loss: 0.6332 - val_acc: 0.9028\n",
      "Train on 58174 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "58174/58174 [==============================] - 4s 75us/step - loss: 0.0545 - acc: 0.9800 - val_loss: 0.5951 - val_acc: 0.9077\n",
      "Train on 58395 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "58395/58395 [==============================] - 4s 75us/step - loss: 0.0549 - acc: 0.9795 - val_loss: 0.5786 - val_acc: 0.9083\n",
      "Train on 58568 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "58568/58568 [==============================] - 4s 74us/step - loss: 0.0565 - acc: 0.9782 - val_loss: 0.5844 - val_acc: 0.9110\n",
      "Train on 58828 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "58828/58828 [==============================] - 4s 75us/step - loss: 0.0570 - acc: 0.9782 - val_loss: 0.5836 - val_acc: 0.9098\n",
      "Train on 58985 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "58985/58985 [==============================] - 4s 75us/step - loss: 0.0572 - acc: 0.9783 - val_loss: 0.5905 - val_acc: 0.9093\n",
      "Train on 59121 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59121/59121 [==============================] - 4s 75us/step - loss: 0.0573 - acc: 0.9787 - val_loss: 0.5063 - val_acc: 0.9143\n",
      "Train on 59181 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59181/59181 [==============================] - 5s 76us/step - loss: 0.0549 - acc: 0.9788 - val_loss: 0.5465 - val_acc: 0.9176\n",
      "Train on 59386 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59386/59386 [==============================] - 4s 75us/step - loss: 0.0569 - acc: 0.9789 - val_loss: 0.5367 - val_acc: 0.9179\n",
      "Train on 59473 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59473/59473 [==============================] - 5s 77us/step - loss: 0.0571 - acc: 0.9784 - val_loss: 0.5509 - val_acc: 0.9147\n",
      "Train on 59583 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59583/59583 [==============================] - 4s 74us/step - loss: 0.0580 - acc: 0.9778 - val_loss: 0.5633 - val_acc: 0.9157\n",
      "Train on 59696 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59696/59696 [==============================] - 4s 75us/step - loss: 0.0592 - acc: 0.9777 - val_loss: 0.5386 - val_acc: 0.9156\n",
      "Train on 59783 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59783/59783 [==============================] - 4s 74us/step - loss: 0.0580 - acc: 0.9779 - val_loss: 0.5477 - val_acc: 0.9172\n",
      "Train on 59833 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59833/59833 [==============================] - 5s 77us/step - loss: 0.0591 - acc: 0.9778 - val_loss: 0.5067 - val_acc: 0.9173\n",
      "Train on 59858 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59858/59858 [==============================] - 4s 74us/step - loss: 0.0596 - acc: 0.9778 - val_loss: 0.5347 - val_acc: 0.9188\n",
      "Train on 59872 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59872/59872 [==============================] - 4s 75us/step - loss: 0.0573 - acc: 0.9785 - val_loss: 0.5122 - val_acc: 0.9196\n",
      "Train on 59874 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59874/59874 [==============================] - 4s 75us/step - loss: 0.0577 - acc: 0.9783 - val_loss: 0.5115 - val_acc: 0.9208\n",
      "Train on 59890 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59890/59890 [==============================] - 4s 75us/step - loss: 0.0565 - acc: 0.9783 - val_loss: 0.5543 - val_acc: 0.9197\n",
      "Train on 59896 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59896/59896 [==============================] - 5s 76us/step - loss: 0.0556 - acc: 0.9793 - val_loss: 0.4935 - val_acc: 0.9224\n",
      "Train on 59891 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59891/59891 [==============================] - 5s 75us/step - loss: 0.0535 - acc: 0.9800 - val_loss: 0.5291 - val_acc: 0.9216\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 5s 76us/step - loss: 0.0534 - acc: 0.9798 - val_loss: 0.5303 - val_acc: 0.9227\n",
      "Train on 59899 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59899/59899 [==============================] - 5s 75us/step - loss: 0.0522 - acc: 0.9808 - val_loss: 0.5263 - val_acc: 0.9232\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0522 - acc: 0.9803 - val_loss: 0.5738 - val_acc: 0.9201\n",
      "Train on 59899 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59899/59899 [==============================] - 4s 75us/step - loss: 0.0531 - acc: 0.9803 - val_loss: 0.5203 - val_acc: 0.9230\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0523 - acc: 0.9799 - val_loss: 0.4985 - val_acc: 0.9240\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0495 - acc: 0.9816 - val_loss: 0.5616 - val_acc: 0.9210\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 5s 75us/step - loss: 0.0532 - acc: 0.9800 - val_loss: 0.5131 - val_acc: 0.9236\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 74us/step - loss: 0.0487 - acc: 0.9815 - val_loss: 0.4996 - val_acc: 0.9256\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0502 - acc: 0.9812 - val_loss: 0.4973 - val_acc: 0.9258\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 5s 75us/step - loss: 0.0499 - acc: 0.9814 - val_loss: 0.5151 - val_acc: 0.9267\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0463 - acc: 0.9823 - val_loss: 0.5105 - val_acc: 0.9264\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 5s 75us/step - loss: 0.0489 - acc: 0.9815 - val_loss: 0.4880 - val_acc: 0.9275\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0473 - acc: 0.9826 - val_loss: 0.4969 - val_acc: 0.9263\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 74us/step - loss: 0.0455 - acc: 0.9826 - val_loss: 0.4958 - val_acc: 0.9277\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 5s 76us/step - loss: 0.0459 - acc: 0.9832 - val_loss: 0.5280 - val_acc: 0.9280\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 74us/step - loss: 0.0457 - acc: 0.9828 - val_loss: 0.4904 - val_acc: 0.9284\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 74us/step - loss: 0.0457 - acc: 0.9830 - val_loss: 0.5159 - val_acc: 0.9274\n",
      "Train on 59900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "59900/59900 [==============================] - 4s 75us/step - loss: 0.0451 - acc: 0.9832 - val_loss: 0.5171 - val_acc: 0.9282\n"
     ]
    }
   ],
   "source": [
    "# Train the model with labeled samples and unlabled samples\n",
    "threshold = 1\n",
    "while True:\n",
    "    xbatch = xun # 无标签数据分 N 拨迭代（这一步似乎很重要）\n",
    "    pbatch = model.predict(xbatch)\n",
    "    idx = np.max(pbatch, axis=-1)\n",
    "    xbatch = xbatch[idx>=threshold]\n",
    "    pbatch = pbatch[idx>=threshold]\n",
    "    pbatch = np.argmax(pbatch, axis=-1)\n",
    "    pbatch = np.eye(10)[pbatch]\n",
    "    model.fit(xbatch, pbatch, \\\n",
    "          batch_size=128, epochs=1, \\\n",
    "          validation_data = (xte, yte), \\\n",
    "          shuffle = True)\n",
    "    if threshold <=0:\n",
    "        break\n",
    "    threshold -= 0.02"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SSL iteratin 0-0, threshold: 0.9, 6642 samples selected\n",
      "Train on 6642 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "6642/6642 [==============================] - 1s 124us/step - loss: 0.0837 - acc: 0.9746 - val_loss: 0.7157 - val_acc: 0.8246\n",
      "SSL iteratin 0-10000, threshold: 0.9, 7633 samples selected\n",
      "Train on 7633 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "7633/7633 [==============================] - 1s 108us/step - loss: 0.0731 - acc: 0.9762 - val_loss: 0.7577 - val_acc: 0.8312\n",
      "SSL iteratin 0-20000, threshold: 0.9, 8076 samples selected\n",
      "Train on 8076 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "8076/8076 [==============================] - 1s 109us/step - loss: 0.0729 - acc: 0.9756 - val_loss: 0.7581 - val_acc: 0.8404\n",
      "SSL iteratin 0-30000, threshold: 0.9, 8293 samples selected\n",
      "Train on 8293 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "8293/8293 [==============================] - 1s 105us/step - loss: 0.0719 - acc: 0.9742 - val_loss: 0.6971 - val_acc: 0.8559\n",
      "SSL iteratin 0-40000, threshold: 0.9, 8410 samples selected\n",
      "Train on 8410 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "8410/8410 [==============================] - 1s 107us/step - loss: 0.0652 - acc: 0.9765 - val_loss: 0.7122 - val_acc: 0.8640\n",
      "SSL iteratin 0-50000, threshold: 0.9, 8572 samples selected\n",
      "Train on 8572 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "8572/8572 [==============================] - 1s 101us/step - loss: 0.0563 - acc: 0.9806 - val_loss: 0.7687 - val_acc: 0.8643\n",
      "SSL iteratin 1-0, threshold: 0.8, 9168 samples selected\n",
      "Train on 9168 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9168/9168 [==============================] - 1s 102us/step - loss: 0.1014 - acc: 0.9634 - val_loss: 0.6553 - val_acc: 0.8718\n",
      "SSL iteratin 1-10000, threshold: 0.8, 9130 samples selected\n",
      "Train on 9130 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9130/9130 [==============================] - 1s 102us/step - loss: 0.0786 - acc: 0.9719 - val_loss: 0.6755 - val_acc: 0.8709\n",
      "SSL iteratin 1-20000, threshold: 0.8, 9227 samples selected\n",
      "Train on 9227 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9227/9227 [==============================] - 1s 100us/step - loss: 0.0819 - acc: 0.9711 - val_loss: 0.6034 - val_acc: 0.8824\n",
      "SSL iteratin 1-30000, threshold: 0.8, 9202 samples selected\n",
      "Train on 9202 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9202/9202 [==============================] - 1s 99us/step - loss: 0.0723 - acc: 0.9728 - val_loss: 0.6294 - val_acc: 0.8836\n",
      "SSL iteratin 1-40000, threshold: 0.8, 9269 samples selected\n",
      "Train on 9269 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9269/9269 [==============================] - 1s 99us/step - loss: 0.0749 - acc: 0.9742 - val_loss: 0.5681 - val_acc: 0.8920\n",
      "SSL iteratin 1-50000, threshold: 0.8, 9163 samples selected\n",
      "Train on 9163 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9163/9163 [==============================] - 1s 101us/step - loss: 0.0632 - acc: 0.9771 - val_loss: 0.5441 - val_acc: 0.8963\n",
      "SSL iteratin 2-0, threshold: 0.7000000000000001, 9549 samples selected\n",
      "Train on 9549 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9549/9549 [==============================] - 1s 101us/step - loss: 0.0863 - acc: 0.9694 - val_loss: 0.5222 - val_acc: 0.8982\n",
      "SSL iteratin 2-10000, threshold: 0.7000000000000001, 9520 samples selected\n",
      "Train on 9520 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9520/9520 [==============================] - 1s 100us/step - loss: 0.0712 - acc: 0.9739 - val_loss: 0.5359 - val_acc: 0.8974\n",
      "SSL iteratin 2-20000, threshold: 0.7000000000000001, 9615 samples selected\n",
      "Train on 9615 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9615/9615 [==============================] - 1s 100us/step - loss: 0.0767 - acc: 0.9708 - val_loss: 0.5200 - val_acc: 0.8995\n",
      "SSL iteratin 2-30000, threshold: 0.7000000000000001, 9592 samples selected\n",
      "Train on 9592 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9592/9592 [==============================] - 1s 98us/step - loss: 0.0708 - acc: 0.9758 - val_loss: 0.4955 - val_acc: 0.9029\n",
      "SSL iteratin 2-40000, threshold: 0.7000000000000001, 9622 samples selected\n",
      "Train on 9622 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9622/9622 [==============================] - 1s 99us/step - loss: 0.0710 - acc: 0.9739 - val_loss: 0.4905 - val_acc: 0.9053\n",
      "SSL iteratin 2-50000, threshold: 0.7000000000000001, 9538 samples selected\n",
      "Train on 9538 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9538/9538 [==============================] - 1s 100us/step - loss: 0.0648 - acc: 0.9761 - val_loss: 0.5295 - val_acc: 0.9011\n",
      "SSL iteratin 3-0, threshold: 0.6000000000000001, 9800 samples selected\n",
      "Train on 9800 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9800/9800 [==============================] - 1s 100us/step - loss: 0.0838 - acc: 0.9686 - val_loss: 0.5071 - val_acc: 0.9055\n",
      "SSL iteratin 3-10000, threshold: 0.6000000000000001, 9815 samples selected\n",
      "Train on 9815 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9815/9815 [==============================] - 1s 100us/step - loss: 0.0800 - acc: 0.9690 - val_loss: 0.5003 - val_acc: 0.9061\n",
      "SSL iteratin 3-20000, threshold: 0.6000000000000001, 9793 samples selected\n",
      "Train on 9793 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9793/9793 [==============================] - 1s 99us/step - loss: 0.0736 - acc: 0.9727 - val_loss: 0.4965 - val_acc: 0.9078\n",
      "SSL iteratin 3-30000, threshold: 0.6000000000000001, 9835 samples selected\n",
      "Train on 9835 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9835/9835 [==============================] - 1s 100us/step - loss: 0.0758 - acc: 0.9708 - val_loss: 0.5055 - val_acc: 0.9048\n",
      "SSL iteratin 3-40000, threshold: 0.6000000000000001, 9844 samples selected\n",
      "Train on 9844 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9844/9844 [==============================] - 1s 101us/step - loss: 0.0739 - acc: 0.9711 - val_loss: 0.5238 - val_acc: 0.9044\n",
      "SSL iteratin 3-50000, threshold: 0.6000000000000001, 9737 samples selected\n",
      "Train on 9737 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9737/9737 [==============================] - 1s 101us/step - loss: 0.0705 - acc: 0.9739 - val_loss: 0.4939 - val_acc: 0.9087\n",
      "SSL iteratin 4-0, threshold: 0.5000000000000001, 9940 samples selected\n",
      "Train on 9940 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9940/9940 [==============================] - 1s 99us/step - loss: 0.0928 - acc: 0.9642 - val_loss: 0.4781 - val_acc: 0.9100\n",
      "SSL iteratin 4-10000, threshold: 0.5000000000000001, 9951 samples selected\n",
      "Train on 9951 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9951/9951 [==============================] - 1s 99us/step - loss: 0.0876 - acc: 0.9660 - val_loss: 0.4908 - val_acc: 0.9037\n",
      "SSL iteratin 4-20000, threshold: 0.5000000000000001, 9964 samples selected\n",
      "Train on 9964 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9964/9964 [==============================] - 1s 99us/step - loss: 0.0829 - acc: 0.9681 - val_loss: 0.4946 - val_acc: 0.9058\n",
      "SSL iteratin 4-30000, threshold: 0.5000000000000001, 9948 samples selected\n",
      "Train on 9948 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9948/9948 [==============================] - 1s 99us/step - loss: 0.0697 - acc: 0.9728 - val_loss: 0.5069 - val_acc: 0.9079\n",
      "SSL iteratin 4-40000, threshold: 0.5000000000000001, 9974 samples selected\n",
      "Train on 9974 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9974/9974 [==============================] - 1s 100us/step - loss: 0.0729 - acc: 0.9733 - val_loss: 0.4995 - val_acc: 0.9104\n",
      "SSL iteratin 4-50000, threshold: 0.5000000000000001, 9859 samples selected\n",
      "Train on 9859 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9859/9859 [==============================] - 1s 98us/step - loss: 0.0772 - acc: 0.9703 - val_loss: 0.4967 - val_acc: 0.9081\n",
      "SSL iteratin 5-0, threshold: 0.40000000000000013, 9989 samples selected\n",
      "Train on 9989 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9989/9989 [==============================] - 1s 98us/step - loss: 0.0795 - acc: 0.9705 - val_loss: 0.4982 - val_acc: 0.9103\n",
      "SSL iteratin 5-10000, threshold: 0.40000000000000013, 9993 samples selected\n",
      "Train on 9993 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9993/9993 [==============================] - 1s 97us/step - loss: 0.0764 - acc: 0.9716 - val_loss: 0.4629 - val_acc: 0.9149\n",
      "SSL iteratin 5-20000, threshold: 0.40000000000000013, 9994 samples selected\n",
      "Train on 9994 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9994/9994 [==============================] - 1s 98us/step - loss: 0.0766 - acc: 0.9706 - val_loss: 0.4594 - val_acc: 0.9149\n",
      "SSL iteratin 5-30000, threshold: 0.40000000000000013, 9990 samples selected\n",
      "Train on 9990 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9990/9990 [==============================] - 1s 98us/step - loss: 0.0706 - acc: 0.9727 - val_loss: 0.4833 - val_acc: 0.9137\n",
      "SSL iteratin 5-40000, threshold: 0.40000000000000013, 9993 samples selected\n",
      "Train on 9993 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9993/9993 [==============================] - 1s 97us/step - loss: 0.0733 - acc: 0.9715 - val_loss: 0.4505 - val_acc: 0.9172\n",
      "SSL iteratin 5-50000, threshold: 0.40000000000000013, 9898 samples selected\n",
      "Train on 9898 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9898/9898 [==============================] - 1s 99us/step - loss: 0.0708 - acc: 0.9730 - val_loss: 0.4636 - val_acc: 0.9168\n",
      "SSL iteratin 6-0, threshold: 0.30000000000000016, 9998 samples selected\n",
      "Train on 9998 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9998/9998 [==============================] - 1s 97us/step - loss: 0.0766 - acc: 0.9694 - val_loss: 0.4330 - val_acc: 0.9200\n",
      "SSL iteratin 6-10000, threshold: 0.30000000000000016, 9999 samples selected\n",
      "Train on 9999 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9999/9999 [==============================] - 1s 97us/step - loss: 0.0663 - acc: 0.9727 - val_loss: 0.4427 - val_acc: 0.9204\n",
      "SSL iteratin 6-20000, threshold: 0.30000000000000016, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 98us/step - loss: 0.0673 - acc: 0.9759 - val_loss: 0.4292 - val_acc: 0.9251\n",
      "SSL iteratin 6-30000, threshold: 0.30000000000000016, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0755 - acc: 0.9733 - val_loss: 0.4023 - val_acc: 0.9257\n",
      "SSL iteratin 6-40000, threshold: 0.30000000000000016, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 98us/step - loss: 0.0672 - acc: 0.9748 - val_loss: 0.3723 - val_acc: 0.9278\n",
      "SSL iteratin 6-50000, threshold: 0.30000000000000016, 9899 samples selected\n",
      "Train on 9899 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9899/9899 [==============================] - 1s 99us/step - loss: 0.0690 - acc: 0.9732 - val_loss: 0.3893 - val_acc: 0.9288\n",
      "SSL iteratin 7-0, threshold: 0.20000000000000015, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 98us/step - loss: 0.0716 - acc: 0.9729 - val_loss: 0.3620 - val_acc: 0.9310\n",
      "SSL iteratin 7-10000, threshold: 0.20000000000000015, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0661 - acc: 0.9750 - val_loss: 0.3665 - val_acc: 0.9341\n",
      "SSL iteratin 7-20000, threshold: 0.20000000000000015, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0653 - acc: 0.9757 - val_loss: 0.3852 - val_acc: 0.9316\n",
      "SSL iteratin 7-30000, threshold: 0.20000000000000015, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0697 - acc: 0.9711 - val_loss: 0.3842 - val_acc: 0.9328\n",
      "SSL iteratin 7-40000, threshold: 0.20000000000000015, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 98us/step - loss: 0.0692 - acc: 0.9748 - val_loss: 0.4096 - val_acc: 0.9280\n",
      "SSL iteratin 7-50000, threshold: 0.20000000000000015, 9900 samples selected\n",
      "Train on 9900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9900/9900 [==============================] - 1s 99us/step - loss: 0.0636 - acc: 0.9759 - val_loss: 0.3908 - val_acc: 0.9326\n",
      "SSL iteratin 8-0, threshold: 0.10000000000000014, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0607 - acc: 0.9761 - val_loss: 0.4097 - val_acc: 0.9303\n",
      "SSL iteratin 8-10000, threshold: 0.10000000000000014, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 96us/step - loss: 0.0599 - acc: 0.9775 - val_loss: 0.3647 - val_acc: 0.9334\n",
      "SSL iteratin 8-20000, threshold: 0.10000000000000014, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 99us/step - loss: 0.0608 - acc: 0.9766 - val_loss: 0.3492 - val_acc: 0.9368\n",
      "SSL iteratin 8-30000, threshold: 0.10000000000000014, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0598 - acc: 0.9779 - val_loss: 0.3626 - val_acc: 0.9366\n",
      "SSL iteratin 8-40000, threshold: 0.10000000000000014, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0573 - acc: 0.9776 - val_loss: 0.3826 - val_acc: 0.9364\n",
      "SSL iteratin 8-50000, threshold: 0.10000000000000014, 9900 samples selected\n",
      "Train on 9900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9900/9900 [==============================] - 1s 97us/step - loss: 0.0619 - acc: 0.9758 - val_loss: 0.3884 - val_acc: 0.9327\n",
      "SSL iteratin 9-0, threshold: 1.3877787807814457e-16, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0608 - acc: 0.9777 - val_loss: 0.3870 - val_acc: 0.9340\n",
      "SSL iteratin 9-10000, threshold: 1.3877787807814457e-16, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 96us/step - loss: 0.0743 - acc: 0.9746 - val_loss: 0.3358 - val_acc: 0.9347\n",
      "SSL iteratin 9-20000, threshold: 1.3877787807814457e-16, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 98us/step - loss: 0.0608 - acc: 0.9776 - val_loss: 0.3337 - val_acc: 0.9395\n",
      "SSL iteratin 9-30000, threshold: 1.3877787807814457e-16, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 97us/step - loss: 0.0641 - acc: 0.9761 - val_loss: 0.3520 - val_acc: 0.9381\n",
      "SSL iteratin 9-40000, threshold: 1.3877787807814457e-16, 10000 samples selected\n",
      "Train on 10000 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "10000/10000 [==============================] - 1s 98us/step - loss: 0.0548 - acc: 0.9804 - val_loss: 0.3490 - val_acc: 0.9380\n",
      "SSL iteratin 9-50000, threshold: 1.3877787807814457e-16, 9900 samples selected\n",
      "Train on 9900 samples, validate on 10000 samples\n",
      "Epoch 1/1\n",
      "9900/9900 [==============================] - 1s 98us/step - loss: 0.0571 - acc: 0.9781 - val_loss: 0.3410 - val_acc: 0.9406\n"
     ]
    }
   ],
   "source": [
    "# Train the model with labeled samples and unlabled samples\n",
    "threshold = 0.9\n",
    "for i in range(10):\n",
    "    for j in range(0, len(xun), 10000):\n",
    "        xbatch = xun[j:j+10000] # 无标签数据分 N 拨迭代（这一步似乎很重要）\n",
    "        pbatch = model.predict(xbatch)\n",
    "        idx = np.max(pbatch, axis=-1)\n",
    "        xbatch = xbatch[idx>threshold]\n",
    "        pbatch = pbatch[idx>threshold]\n",
    "        pbatch = np.argmax(pbatch, axis=-1)\n",
    "        pbatch = np.eye(10)[pbatch]\n",
    "        print('SSL iteratin {}-{}, threshold: {}, {} samples selected'.format(i,j, threshold, xbatch.shape[0]))\n",
    "\n",
    "        model.fit(xbatch, pbatch, \\\n",
    "              batch_size=128, epochs=1, \\\n",
    "              validation_data = (xte, yte), \\\n",
    "              shuffle = True)\n",
    "    threshold -= 0.1\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
